package org.sssc2009.guessxcess.client;

import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.CheckChangedEvent;
import com.extjs.gxt.ui.client.event.CheckChangedListener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreFilter;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.StoreFilterField;
import com.extjs.gxt.ui.client.widget.layout.AccordionLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.CheckCascade;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Gwt_guessXcess implements EntryPoint {

	final HorizontalPanel mainPanel = new HorizontalPanel();
	final VerticalPanel verticalPanelL = new VerticalPanel();
	final VerticalPanel verticalPanelR = new VerticalPanel();
	ContentPanel diseasePanel;
	ContentPanel dietPanel;
	ContentPanel ingredientPanel;
	private TreeStore<ModelData> recipeStore;

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		addPanel();

		addTreeToPanel(ingredientPanel, DataProvider.getIngredients(), "Please select Ingredients:");
		addTreeToPanel(diseasePanel, DataProvider.getDiseases(), "Please select Diseases:");
		addTreeToPanel(dietPanel, DataProvider.getDiets(), "Please select Diets:");

		addRecipeTree();

		verticalPanelL.setLayout(new FlowLayout(10));
		verticalPanelR.setLayout(new FlowLayout(10));

		mainPanel.add(verticalPanelL);
		mainPanel.add(verticalPanelR);
		RootPanel.get("theBody").add(mainPanel);

	}

	private void addPanel() {
		ContentPanel panel = new ContentPanel();
		panel.setHeading("Preference Chooser");
		panel.setBodyBorder(false);

		panel.setLayout(new AccordionLayout());

		ingredientPanel = new ContentPanel();
		ingredientPanel.setHeading("Ingredients");
		ingredientPanel.setLayout(new FitLayout());
		panel.add(ingredientPanel);

		diseasePanel = new ContentPanel();
		diseasePanel.setHeading("Diseases");
		diseasePanel.setLayout(new FitLayout());
		panel.add(diseasePanel);

		dietPanel = new ContentPanel();
		dietPanel.setHeading("Diet");
		dietPanel.setLayout(new FitLayout());
		panel.add(dietPanel);

		panel.setSize(300, 600);
		verticalPanelL.add(panel);
	}

	private void addRecipeTree() {
		FormPanel panel = new FormPanel();
		panel.setHeading("Resulting Recipes:");
		panel.setLayout(new FitLayout());
		verticalPanelR.add(panel);

		VerticalPanel vp = new VerticalPanel();
		panel.add(vp);

		recipeStore = new TreeStore<ModelData>();
		recipeStore.add(DataProvider.getRecipes().getChildren(), true);
		final TreePanel<ModelData> tree = new TreePanel<ModelData>(recipeStore);

		tree.setAutoLoad(true);
		tree.setDisplayProperty("name");

		Menu contextMenu = new Menu();
		contextMenu.setWidth(140);

		MenuItem open = new MenuItem();
		open.setText("Open Recipe");
		open.addSelectionListener(new SelectionListener<MenuEvent>() {
			public void componentSelected(MenuEvent ce) {
				Window.open("http://libresource.loria.fr/mediawiki/index.php/3-step_veggie_pizza", "_blank", "");
			}
		});
		contextMenu.add(open);

		tree.setContextMenu(contextMenu);

		LayoutContainer container = new LayoutContainer();
		container.setSize(600, 533);
		container.setBorders(true);
		container.setLayout(new FitLayout());
		container.add(tree);

		vp.add(addFilterToStore(recipeStore));
		vp.add(container);
	}

	private void addTreeToPanel(ContentPanel panel, Concept model, String description) {
		VerticalPanel vPanel = new VerticalPanel();
		panel.add(vPanel);

		TreeStore<ModelData> store = new TreeStore<ModelData>();
		store.add(model.getChildren(), true);
		final TreePanel<ModelData> tree = new TreePanel<ModelData>(store);

		tree.setCheckable(true);
		tree.setCheckStyle(CheckCascade.CHILDREN);
		tree.setAutoLoad(true);
		tree.setExpanded(model, true, true);
		tree.setDisplayProperty("name");
		
		tree.addCheckListener(new CheckChangedListener<ModelData>() {
			@Override
			public void checkChanged(CheckChangedEvent<ModelData> event) {
				Info.display("Refining Selection", "will filter food containing meat", "");
				updateRecipes();
			}
		});

//		tree.addListener(Events.SelectionChange, new Listener<TreePanelEvent<ModelData>>() {
//
//			public void handleEvent(TreePanelEvent<ModelData> be) {
//				Info.display("Checked Items", "test", "");
//			}
//		});

		final Html prefHtml = new Html(description);
		prefHtml.setStyleName("pad-text");

		vPanel.add(prefHtml);
		vPanel.add(addFilterToStore(store));
		vPanel.add(tree);
	}

	private StoreFilterField<ModelData> addFilterToStore(Store<ModelData> store) {
		StoreFilterField<ModelData> filter = new StoreFilterField<ModelData>() {

			@Override
			protected boolean doSelect(Store<ModelData> store, ModelData parent, ModelData record, String property,
					String filter) {
				// only match leaf nodes
				if (false == record instanceof Individual) {
					return false;
				}
				String name = record.get("name");
				name = name.toLowerCase();
				if (name.startsWith(filter.toLowerCase())) {
					return true;
				}
				return false;
			}

		};
		filter.bind(store);
		return filter;
	}

	private void updateRecipes() {
		StoreFilter<ModelData> filter = new StoreFilter<ModelData>() {

			@Override
			public boolean select(Store<ModelData> store, ModelData parent, ModelData item, String property) {
				String name = item.get("name");
				name = name.toLowerCase();
				if (name.startsWith("RecipeChicken".toLowerCase())) {
					return false;
				}
				return true;
			}

		};
		recipeStore.addFilter(filter);
	}

}
